package main

import (
	"fmt"
    //"log"
    "os"
    "bufio"
    "syscall"
	"runtime"
    "sync"
    "strconv"
    "strings"
    "time"
)

var (
    pipeFile_CpuLoad string ="/tmp/CpuLoad.ipc"
    namedPipeWriter_CpuLoad *os.File
	//定义:任务队列
	waitgroup 	sync.WaitGroup
	
  CPU_MAX_CAPACITY int
  // task 最大执行次数 
  MAX_EXE_CNT int64 = 9999999999999999
  // task 延时模拟CPU负载, 默认值: 100mS
  taskDelay int64 = 100000000
  // task 延时基数, 单位: Nanosecond
  taskDelayBase float32 = 5000.0
  // task 并发数量
  taskNum int = 8
)

func task(num int64) { //9999999999999999
  	var i int64
    for i=1; i<=MAX_EXE_CNT; i++ {
		num = num+i
		num = num-i
		num = num*i
		num = num/i
        time.Sleep(time.Duration(taskDelay)*time.Nanosecond)
	}
	//任务完成，将任务队列中的任务数量-1，其实.Done就是.Add(-1)
    waitgroup.Done()
    MyLog.Info(fmt.Sprintf("task[%d] completed.", num))
}

func namedPipeInit(pipeFile string) {
    os.Remove(pipeFile)
    err := syscall.Mkfifo(pipeFile, 0666)
    if err != nil {
        MyLog.Error("create named pipe error, %v", err)
    }else {

    }
}

func namePipeBlockReaderInit(pipeFile string) *bufio.Reader {
    file, err := os.OpenFile(pipeFile, os.O_RDWR, os.ModeNamedPipe)
    if err != nil {
        MyLog.Error("error opening file, %v", err)
    } else{

    }
    reader := bufio.NewReader(file)
    return reader
}

func namePipeWriterInit(pipeFile string) *os.File {
    writer, err := os.OpenFile(pipeFile, os.O_RDWR, 0777)
    if err != nil {
        MyLog.Error("error opening file, %v", err)
    } else{

    }
    return writer
}

func math_fx( orbit_duration int) int64 {
    var task_delay int64
    // 反比例函数拟合: 公转周期 与 CPU负载延时 之间的数学关系
    // 公转周期: 线性减小
    // CPU负载延时基数: 5000 Nanosecond
    
    var f float32
    if orbit_duration >= 12 {
        f = taskDelayBase
    }else{
        f = taskDelayBase * ( 1.0/float32(CPU_MAX_CAPACITY-orbit_duration) )
    }
    task_delay = int64(f)
    return task_delay
}

func goTask_SetCpuSleep() {
    reader := namePipeBlockReaderInit(pipeFile_CpuLoad)
    for {
        // 命名管道: 消息体结束符 '\n'
        line, err := reader.ReadBytes('\n')
        if err == nil {
            arr:=strings.Split(string(line), "\n")
            //log.Printf("orbit_duration: %s", arr[0])
            dur_f, _ := strconv.ParseFloat(arr[0], 64)
            dur_i := int(dur_f)
            ///////////////////////////////////////////////////////////////////////////
            //设置最大的可同时使用的CPU核数和实际cpu核数一致
            // reference link: https://blog.csdn.net/Jailman/article/details/78520472
            runtime.GOMAXPROCS(32)
            // 数学关系 转换
            taskDelay = math_fx(dur_i)
            MyLog.Info(fmt.Sprintf("delay %d Nanosecond", taskDelay))

        }
    }
}

func goTask_CpuLoad() {
    for {
        for i := 1; i <= taskNum; i++ {
            waitgroup.Add(1) //每创建一个goroutine，就把任务队列中任务的数量+1
            go task( int64(i) )
        }
        waitgroup.Wait() //Wait()这里会发生阻塞，直到队列中所有的任务结束就会解除阻塞
    }
}

func myLogic_Init(orbit_duration_normal string) {
    arr:=strings.Split(orbit_duration_normal, "s")
    dur_f, _ := strconv.ParseFloat(arr[0], 64)
  CPU_MAX_CAPACITY = int(dur_f)
  MyLog.Info(fmt.Sprintf("CPU_MAX_CAPACITY %d", CPU_MAX_CAPACITY))
  namedPipeInit(pipeFile_CpuLoad);
  namedPipeWriter_CpuLoad = namePipeWriterInit(pipeFile_CpuLoad);
  go goTask_SetCpuSleep()
  go goTask_CpuLoad()
}



func setCpuLoad(orbit_duration string)  {
    // 命名管道: 消息体结束符 '\n'
    ipcmsg := fmt.Sprintf("%s\n", orbit_duration)

    namedPipeWriter_CpuLoad.WriteString(ipcmsg)    

}